/**
 * tz路由统一跳转
 */
import Taro from "@tarojs/taro";
import { onUnmounted } from "vue";

export const useTzRouter = () => {
  //切面pages
  const pages = Taro.getCurrentPages();

  //当前实例子
  const instance = pages[pages.length - 1];
  const { route, path, $taroParams } = instance;
  const cPath = route || path.split("?")[0];
  const taroParams = decodeObj($taroParams);

  /**
   * 跳转到 tabBar 页面，并关闭其他所有非 tabBar 页面
   * @param {Object} option
   */
  const switchTab = (option) => {
    const { path: url, complete, fail, success } = option;
    return Taro.switchTab({ url, complete, fail, success });
  };

  /**
   * 跳转到新的页面
   * @param {Object} option {path,query:{}}
   */
  const navigateTo = (option) => {
    const { path, query } = option;
    const args = objToUrl(query);
    if (!args) return Taro.navigateTo({ url: path });
    if (path.includes("?")) {
      return Taro.navigateTo({ url: path + "&" + args });
    }
    return Taro.navigateTo({ url: path + "?" + args });
  };

  /**
   * 关闭当前页面，返回上一页面或多级页面
   * @param {Object} option {delta: 1}
   */
  const navigateBack = (option = { delta: 1 }) => {
    option.delta = option.delta || 1;
    const { delta, event } = option;
    const prePage = pages[pages.length - delta - 1];
    if (event) {
      const path = prePage.route || prePage.path.split("?")[0];
      Taro.eventCenter.trigger(path, event);
    }
    return Taro.navigateBack(option);
  };

  /**
   * 关闭所有页面，打开到应用内的某个页面
   * @param {Object} option
   */
  const reLaunch = (option) => {
    const { path, query } = option;
    const args = objToUrl(query);
    if (!args) return Taro.reLaunch({ url: path });
    if (path.includes("?")) {
      return Taro.reLaunch({ url: path + "&" + args });
    }
    return Taro.reLaunch({ url: path + "?" + args });
  };

  /**
   * 关闭当前页面，跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面。
   * @param {Object} options
   */
  const redirectTo = (option) => {
    const { path, query } = option;
    const args = objToUrl(query);
    if (!args) return Taro.redirectTo({ url: path });
    if (path.includes("?")) {
      return Taro.redirectTo({ url: path + "&" + args });
    }
    return Taro.redirectTo({ url: path + "?" + args });
  };

  /**
   * 全局事件订阅
   */
  const EventChannel = {
    on: (eventName, fun) => {
      Taro.eventCenter.on(eventName, fun);
    },
    emit: (eventName, args) => {
      Taro.eventCenter.trigger(eventName, args);
    },
    off: (eventName, fun) => {
      Taro.eventCenter.off(eventName, fun);
    },
  };

  onUnmounted(() => {
    Taro.eventCenter.off(cPath);
  });

  return {
    navigateBack,
    switchTab,
    navigateTo,
    reLaunch,
    redirectTo,
    EventChannel,
    route: { path: cPath, query: taroParams },
  };
};

/**
 * 对象类型参数 转url
 * @param {} query
 * @returns
 */
const objToUrl = (query) => {
  if (!query) return "";
  //对象转成url 参数，只支持一层对象
  let args = "";
  // eslint-disable-next-line no-unused-vars
  for (const key in query) {
    if (query.hasOwnProperty(key)) {
      let value = query[key];
      if (value === "undefined") continue;
      if (value === null) value = ""; //处理null会被转换null字符串
      value = value ? encodeURIComponent(value) : value;
      args += `&${key}=${value}`;
    }
  }
  return args.substr(1);
};

/**
 * 对象特殊字符 decode
 * @param {} query
 * @returns
 */
const decodeObj = (query) => {
  //对象转成url 参数，只支持一层对象
  const obj = {};
  // eslint-disable-next-line no-unused-vars
  for (const key in query) {
    if (Object.hasOwnProperty.call(query, key)) {
      if (key === "stamp" || key === "$taroTimestamp") continue;
      const value = query[key];
      obj[key] = decodeURIComponent(value);
    }
  }
  return obj;
};
